`ifndef SEQUENCER_SVH
`define SEQUENCER_SVH

class sequencer #(type T = transaction);
	int unsigned num_trans;
	T tr;

	covergroup cg (int w, string instComment);
		// 收集覆盖组cg的类型覆盖率和覆盖组实例的覆盖率
		option.per_instance = 1;
		type_option.comment = "coverage model for property a and b";
		type_option.strobe = 1; // 在每个时间片的最后时刻采样
		// 将所有实例的覆盖信息合并到类型覆盖信息中
		type_option.merge_instances = 1;
		// 每个覆盖组实例的注释信息
		option.comment = instComment;
		track_a : coverpoint tr.a
		{
			// 使用权重值2计算覆盖组实例的覆盖率
			option.weight = 2;
			// 使用权重值3计算覆盖组cg的类型覆盖率
			type_option.weight = 3;
			// 注意：type_option.weight = w将导致编译出错
		}
		track_b : coverpoint tr.b
		{
			// 使用权重值w计算覆盖组实例的覆盖率
			option.weight = w;
			// 使用权重值5计算覆盖组cg的类型覆盖率
			type_option.weight = 5;
		}
	endgroup
		
	function new();
		cg = new(3, "cg"); // 覆盖点track_b的option.weight被设置为3
	endfunction

	virtual task main();
		tr = new();
		repeat(num_trans) begin
			assert(tr.randomize());
			tr.print("sequencer");
			cg.sample();
		end
		$display("instance coverage=%f", cg.get_inst_coverage()); // 获取覆盖组实例的功能覆盖率
		$display("type coverage=%f", cg.get_coverage()); // 获取覆盖组的功能覆盖率
		$display("total coverage=%f", $get_coverage()); // 获取测试平台总体功能覆盖率，其值由所有的覆盖组的功能覆盖率决定
	endtask
endclass

`endif
